#! /usr/bin/env python
# -*- coding:utf-8 -*-
# @Time : 2020/11/25 21:05
# @Author : youngchaolin

count = 0


# def func():
#     global count
#     count+=1
#     print(count)
#     func()
#     print(456)

# func()

# 为循环自定义深度，可以加条件
def func():
    global count
    count += 1
    print(count)
    if count == 3: return
    func()
    print(456)


func()

# ecursionError: maximum recursion depth exceeded while calling a Python object

# 最大递归深度 1000层
'''
上面的函数，执行func()就是第一次，然后打印1时，已经调用2次
当打印998时，已经调用999次，最后再执行func()时，报错了，总共就是1000次

为了节省内存空间，不要让用户无限使用内存空间而设置的
递归虽然默认设置1000次，会有担心次数不够的问题，但是如果1000次递归都解决不了的问题，说明不
适合用递归
递归，也可以通过方法来设置深度，方法是setrecursionlimit
递归和循环的比较：
1 递归不是万能的
2 递归比循环更加占用空间，最后空间也会转化为时间
'''

import sys


# sys.setrecursionlimit(1000000)

# 重新打印
# func()

# 带参数的函数
# 一个函数要能结束，必须在函数里写return，而且这个return必须是可以达到的
def func(count):
    count += 1
    print(count)
    # count和10相除，商5余3时，停下
    if divmod(count, 10) == (5, 3):
        return
    func(count)


func(1)


# 如果想让里层函数的返回值被外层函数接收，直接返回里层函数的执行结果
def func(count):
    count += 1
    print(count)
    # count和10相除，商5余3时，停下
    if divmod(count, 10) == (5, 3):
        return '我是最里层函数'
    ret = func(count)
    print(count, '->', ret)
    return ret


print(func(1))

'''
递归，一个是递，一个是归，递是一层层的走里走，归是一层层的往外层返回结果
'''


# 练习
# 1 计算阶乘
def factorial_func(n):
    if n == 1:
        return 1
    else:
        return n * factorial_func(n - 1)

# 计算阶乘方法优化


# 计算
print(f'递归结果为：{factorial_func(4)}')

# 2 查看一个文件夹下的所有文件，文件夹下还有文件夹，不能用walk
print('----查看一个文件夹下的所有文件----')
lst = []
import os


def get_file(path):
    ret = os.listdir(path)
    for sub_path in ret:
        # 如果是目录
        if os.path.isdir(path + '/' + sub_path):
            # print(sub_path,'是目录')
            get_file(path + '/' + sub_path)
        # 如果是文件
        elif os.path.isfile(path + '/' + sub_path):
            # print(sub_path,'是文件')
            # lst.append(sub_path)
            lst.append(sub_path)


# get_file('I:\BOE大数据')
print(lst, len(lst))
# 3 计算一个文件夹下的所有文件的大小，文件夹下还有文件夹，不能用walk
print('----查看一个文件夹下的所有文件的大小----')


def get_file_size(path):
    ret = os.listdir(path)
    for sub_path in ret:
        # 如果是目录
        if os.path.isdir(path + '/' + sub_path):
            # print(sub_path,'是目录')
            get_file_size(path + '/' + sub_path)
        # 如果是文件
        elif os.path.isfile(path + '/' + sub_path):
            print(sub_path, ':', os.path.getsize(path + '/' + sub_path) / 1024, 'KB')


# get_file_size('I:\BOE大数据')


# 4 计算斐波那契数列 0 1 1 2 3 5 8 13 21 34 55 89...
def get_Fibonacci(n):
    if n == 1:
        return 0
    elif n == 2:
        return 1
    else:
        ret = get_Fibonacci(n - 1) + get_Fibonacci(n - 2)
        # 打印n
        # print(n,':',ret)
        return ret


print('----斐波那契数列----')
import time
start=time.time()
# print(start,type(start))
# for n in range(1, 50):
#     print(get_Fibonacci(n))
end=time.time()
print(f'计算斐波那契数列的时间为{end-start}秒')

# 优化上面斐波那契数列计算 TODO
dic={}
def get_Fibonacci_new(n):
    if n == 1:
        dic[n]=dic.get(n,0)+0
        return 0
    elif n == 2:
        dic[n] = dic.get(n, 0) + 1
        return 1
    else:
        if dic.get(n-1) and dic.get(n-2):
            dic[n]=dic.get(n-1)+dic.get(n-2)
            return dic.get(n)
        # else:
        #     ret = get_Fibonacci(n - 1) + get_Fibonacci(n - 2)
        #     # 打印n
        #     # print(n,':',ret)
        #     return ret

# get_Fibonacci(100)
print('----斐波那契数列-更新后代码----')
start=time.time()
for n in range(1, 30):
    print(get_Fibonacci(n))
end=time.time()
print(f'计算斐波那契数列（更新代码后）的时间为{end-start}秒')
print(dic)

# 5 三级菜单 TODO
menu = {
    '北京': {
        '海淀': {
            '五道口': {
                'soho': {},
                '网易': {},
                'google': {}
            },
            '中关村': {
                '爱奇艺': {},
                '汽车之家': {},
                'youku': {},
            },
            '上地': {
                '百度': {},
            },
        },
        '昌平': {
            '沙河': {
                '老男孩': {},
                '北航': {},
            },
            '天通苑': {},
            '回龙观': {},
        },
        '朝阳': {},
        '东城': {},
    },
    '上海': {
        '闵行': {
            "人民广场": {
                '炸鸡店': {}
            }
        },
        '闸北': {
            '火车战': {
                '携程': {}
            }
        },
        '浦东': {},
    },
    '山东': {},
}

print(menu)

# 递归实现答案
def threeLM(dic):
    while True:
        for k in dic:print(k)
        key = input('input>>').strip()
        if key == 'b' or key == 'q':return key
        elif key in dic.keys() and dic[key]:
                ret = threeLM(dic[key])
                if ret == 'q': return 'q'

# threeLM(menu)

# 堆栈实现
l = [menu]
while l:
    for key in l[-1]:print(key)
    k = input('input>>').strip()   # 北京
    if k in l[-1].keys() and l[-1][k]:l.append(l[-1][k])
    elif k == 'b':l.pop()
    elif k == 'q':break

